#ifndef X1C_H
#define X1C_H

#include "common.h"
#include "t13.h"

#include <array>
#include <vector>

template <AllegroVersion version>
struct x1C_header
{
    uint16_t t;
    uint8_t n;
    uint8_t un9;
    uint32_t k;
    uint32_t next;
    uint32_t pad_str;
    uint32_t un0_0;
    uint32_t un0_1;
    uint32_t pad_path; // x03
    uint16_t un0_3;
    uint32_t un0_4;
    uint32_t un0_5;
    uint32_t un1;
    uint16_t un2_0;
    uint16_t un2_1;
    uint16_t un3;
    uint16_t size_hint;
    std::array<int32_t, 4> coords2;
    uint32_t un4;
    uint32_t un5;
#if __cplusplus >= 202002L
    COND_FIELD(version >= A_172, uint32_t, un7);
#endif
    uint32_t un6;

    uint32_t TAIL;
    operator x1C_header<A_174>() const;
    static constexpr AllegroVersion versions[2] = {A_165, A_172};
};

#if __cplusplus >= 202002L
template <AllegroVersion version> requires(version == A_165 || version == A_166)
struct x1C_header<version>
{
    uint16_t t;
    uint8_t n;
    uint8_t un9;
    uint32_t k;
    uint32_t next;
    uint32_t pad_str;
    uint32_t un0_0;
    uint32_t un0_1;
    uint32_t pad_path; // x03
    uint16_t un0_3;
    uint32_t un0_4;
    uint32_t un0_5;
    uint32_t un1;
    uint16_t un2_0;
    uint16_t un2_1;
    uint16_t un3;
    uint16_t size_hint;
    std::array<int32_t, 4> coords2;
    uint32_t un4;
    uint32_t un5;
    uint32_t un6;
    uint32_t un8[8];

    uint32_t TAIL;
    operator x1C_header<A_174>() const;
    static constexpr AllegroVersion versions[2] = {A_165, A_172};
};
#else
template <> struct x1C_header<A_165>
{
    uint16_t t;
    uint8_t n;
    uint8_t un9;
    uint32_t k;
    uint32_t next;
    uint32_t pad_str;
    uint32_t un0_0;
    uint32_t un0_1;
    uint32_t pad_path; // x03
    uint16_t un0_3;
    uint32_t un0_4;
    uint32_t un0_5;
    uint32_t un1;
    uint16_t un2_0;
    uint16_t un2_1;
    uint16_t un3;
    uint16_t size_hint;
    std::array<int32_t, 4> coords2;
    uint32_t un4;
    uint32_t un5;
    uint32_t un6;
    uint32_t un8[8];

    uint32_t TAIL;
    operator x1C_header<A_174>() const;
    static constexpr AllegroVersion versions[2] = {A_165, A_172};
};
template<> struct x1C_header<A_166> : x1C_header<A_165> {};


template <> struct x1C_header<A_172>
{
    uint16_t t;
    uint8_t n;
    uint8_t un9;
    uint32_t k;
    uint32_t next;
    uint32_t pad_str;
    uint32_t un0_0;
    uint32_t un0_1;
    uint32_t pad_path; // x03
    uint16_t un0_3;
    uint32_t un0_4;
    uint32_t un0_5;
    uint32_t un1;
    uint16_t un2_0;
    uint16_t un2_1;
    uint16_t un3;
    uint16_t size_hint;
    std::array<int32_t, 4> coords2;
    uint32_t un4;
    uint32_t un5;
    uint32_t un7;
    uint32_t un6;

    uint32_t TAIL;
    operator x1C_header<A_174>() const;
    static constexpr AllegroVersion versions[2] = {A_165, A_172};
};
template <> struct x1C_header<A_174> : x1C_header<A_172> {};
#endif

// x1C shows how to draw pads
template <AllegroVersion version>
struct x1C
{
    x1C_header<version> hdr;
    std::vector<t13<version>> parts;
    
    operator x1C<A_174>() const;
    static constexpr AllegroVersion versions[2] = {A_165, A_172};
};

#endif // X1C_H
